package com.zkingsoft.common.actions;

import com.matrix.core.constance.MatrixConstance;
import com.matrix.core.constance.SystemErrorCode;
import com.matrix.core.exception.GlobleException;
import com.matrix.core.pojo.AjaxResult;
import com.matrix.core.tools.LogUtil;
import com.matrix.core.tools.RSAUtils;
import com.matrix.core.tools.StringUtils;
import com.matrix.core.tools.WebUtil;
import com.matrix.core.web.BaseAction;
import com.zkingsoft.common.authority.DefaultAuthorityManager;
import com.zkingsoft.common.authority.strategy.AccountPasswordLogin;
import com.zkingsoft.common.authority.strategy.LoginStrategy;
import com.zkingsoft.common.bean.SysCompany;
import com.zkingsoft.common.bean.SysUsers;
import com.zkingsoft.common.constance.AppConstance;
import com.zkingsoft.common.constance.AppMessageCode;
import com.zkingsoft.common.dao.SysCompanyDao;
import com.zkingsoft.common.service.SysUsersService;
import com.zkingsoft.web.tool.SystemConstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.security.Key;
import java.util.Map;

/**
 * @description 通用控制器,本action未经session过验证器
 * @author 姜友瑶
 * @email 935090232@qq.com
 * @date 2016-06-26
 */
@RequestMapping(value = "/common")
@Controller
public class CommonAction extends BaseAction {

	/**
	 * 管理员主页
	 */
	private static final String ADMIN_REDIRECT_INDEX = "admin/redirect/index";

	@Autowired
	SysUsersService sysUsersService;

	@Autowired
	SysCompanyDao companyDao;

	@Autowired
	DefaultAuthorityManager authorityManager;

	/**
	 * @Description: 页面定向方法，每个权限模块公用一个，每个模块共享一个一级路径，已便于进行权限过滤
	 * @date 2016年8月30日
	 */
	@RequestMapping(value = "/redirect/{page1}/{page2}")
	public String redirect(@PathVariable("page1") String page1, @PathVariable("page2") String page2) {
		return "common/" + page1 + "/" + page2;
	}

	/**
	 * 
	 * @Description: 页面定向方法，每个权限模块公用一个，每个模块共享一个一级路径，已便于进行权限过滤
	 * @date 2016年8月30日
	 */
	@RequestMapping(value = "/redirect/{page1}")
	public String redirect(@PathVariable("page1") String page1) {
		return "common/" + page1;
	}

	/**
	 * 
	 * @Description: 登录验证
	 * @author:姜友瑶
	 * @param user
	 * @param request
	 * @return 返回类型 AjaxResult
	 * @date 2016年8月30日
	 */
	@RequestMapping(value = "/dologin")
	public @ResponseBody AjaxResult dologin(HttpServletRequest request, SysUsers user) {

		decryptAccountAndPassword(user);

		LoginStrategy apLogin = new AccountPasswordLogin(user, sysUsersService);

		user = authorityManager.login(apLogin);

		authorityManager.initUserPower();

		AjaxResult result = new AjaxResult();
		result.setStatus(AjaxResult.STATUS_SUCCESS);
		LogUtil.info("#用户登录成功 账号={}#", user.getSuAccount());

		WebUtil.setSessionAttribute("company",  companyDao.selectById(user.getCompanyId()));


		switch (user.getSuUserType()) {
		// 开发人员
		case AppConstance.USER_TYPE_DEVELOPER:
			result.setPage("developer/redirect/index");
			break;
		// 超级管理员
		case AppConstance.USER_TYPE_SUPER:
			result.setPage("super/redirect/index");
			break;
		// 企业管理员
		case AppConstance.USER_TYPE_ADMIN:
			// 判断用户登录域名是否正确
			// 获得请求的域名
			checkHost(user);
			result.setPage(ADMIN_REDIRECT_INDEX);
			break;
		// 企业用户
		case AppConstance.USER_TYPE_EMPLOYEE:
			checkHost(user);
			result.setPage(ADMIN_REDIRECT_INDEX);
			break;
		// 普通用户
		case AppConstance.USER_TYPE_CUSTIMER:
			result.setPage(ADMIN_REDIRECT_INDEX);
			break;
		default:// 不能识别的用户
			result.setPage("common/redirect/404");
		}
		return result;
	}

	/**
	 * 检查用户是否从分配的域登录
	 * @author JIANGYOUYAO
	 * @email 935090232@qq.com
	 * @date 2019年1月27日
	 * @param user
	 */
	private void checkHost(SysUsers user) {
		if(!SystemConstance.DEBUG){
			String host = WebUtil.getRequest().getServerName();
			SysCompany company = companyDao.selectById(user.getCompanyId());
			String hostCode=company.getComWebUrl();
			if (!host.contains(hostCode)) {
				LogUtil.info("用户从其他域名登录，登录域名不匹配host={},code={}",host,hostCode);
				throw new GlobleException(AppMessageCode.User.ACCOUNT_NOT_EXIST);
			}
		}
	}

	/**
	 * 对用户账号密码进行解密
	 * 
	 * @author JIANGYOUYAO
	 * @email 935090232@qq.com
	 * @date 2017年12月11日
	 * @param user
	 */
	private void decryptAccountAndPassword(SysUsers user) {

		String privateKey = WebUtil.getSessionAttribute(MatrixConstance.PRIVATE_KEY);
		if (StringUtils.isBlank(privateKey)) {
			throw new GlobleException(SystemErrorCode.REQUEST_INVALID);
		}

		try {
			// 账号解密
			byte[] acccountData = RSAUtils.decryptByPrivateKey(user.getSuAccount(), privateKey);
			user.setSuAccount(new String(acccountData));
			// 密码解密
			byte[] passWordData = RSAUtils.decryptByPrivateKey(user.getSuPassword(), privateKey);
			user.setSuPassword(new String(passWordData));

		} catch (Exception e) {
			LogUtil.error("用户账号密码解密失败", e);
			throw new GlobleException(SystemErrorCode.SYSTEM_RUNNING_ERROR);
		}

	}

	/**
	 * 
	 * @Description: 用户退出系统
	 * @author:姜友瑶
	 * @return
	 * @throws Exception
	 *             返回类型 String
	 * @date 2016年11月15日
	 */
	@GetMapping(value = "/loginOut")
	public String loginOut() {
		authorityManager.getLoginOut();
		return "redirect:/do/common/toLogin";
	}

	/**
	 * 进入登录界面
	 * 
	 * @author JIANGYOUYAO
	 * @email 935090232@qq.com
	 * @date 2017年12月11日
	 * @return
	 * @throws Exception
	 */
	@GetMapping(value = "/toLogin")
	public String toLogin() {
		// 初始化登录密钥
		Map<String, Key> keyMap;
		try {
			keyMap = RSAUtils.initKey();
			String publicKey = RSAUtils.getPublicKey(keyMap);
			String privateKey = RSAUtils.getPrivateKey(keyMap);
			WebUtil.setRequestAttribute(MatrixConstance.PUPBLIC_KEY, publicKey);
			WebUtil.setSessionAttribute(MatrixConstance.PRIVATE_KEY, privateKey);
		} catch (Exception e) {
			LogUtil.error("#初始化登录加密秘钥错误#", e);
			throw new GlobleException(SystemErrorCode.SYSTEM_RUNNING_ERROR);
		}

		return "common/login";
	}

}